﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Infrastructure;
using PluginManager;
using System.Collections.ObjectModel;
using Microsoft.Practices.Prism.Commands;
using System.Windows.Input;
using System.Windows;
using Microsoft.Practices.Prism.Regions;
using System.Collections;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Prism.Events;
using Infrastructure.Events;

namespace Header.ViewModel
{
    public class HeaderViewModel : ViewModelBase
    {
        private ObservableCollection<string> menuItems;
        private List<NamePair> names;
        private ICommand selectionChanged;
        private IRegionManager regionManager;
        private int selectedIndex = 0;
        public HeaderViewModel(IUnityContainer container, IEventAggregator eventAggregator, IRegionManager regionManager)
            : base(container, eventAggregator)
        {
            SelectionChanged = new DelegateCommand<object>(OnSelectionChanged);
            this.regionManager = regionManager;
            EventAggregator.GetEvent<OnSwitchUserEvent>().Subscribe(OnSwitchUser);
            Refresh();
        }

        public void OnSwitchUser(object sender)
        {
            Refresh();
            IRegion region = regionManager.Regions["ContentRegion"];
            RemoveViewsInContentRegion(region);
            this.SelectedIndex = -1;
            this.SelectedIndex = 0;
        }

        private void Refresh()
        {
            MenuItems = new ObservableCollection<string>();
            PluginsManagement.Instance.RegistInstancesBasedOnPermission();
            names = PluginsManagement.Instance.GetAllPluginsNamePair();
            names.ForEach(p => MenuItems.Add(p.Name));
        }

        public ObservableCollection<string> MenuItems
        {
            get { return menuItems; }
            set
            {
                menuItems = value;
                OnPropertyChanged("MenuItems");
            }
        }

        public ICommand SelectionChanged
        {
            get
            {
                return selectionChanged;
            }
            set
            {
                selectionChanged = value;
                OnPropertyChanged("SelectionChanged");
            }
        }
        public int SelectedIndex
        {
            get
            {
                return selectedIndex;
            }
            set
            {
                selectedIndex = value;
                OnPropertyChanged("SelectedIndex");
            }
        }

        public void OnSelectionChanged(object sender)
        {
            IList items = sender as IList;
            if (items.Count == 1)
            {
                NamePair np = names.FirstOrDefault(p => p.Name == items[0].ToString());
                if (np != null)
                {
                    DependencyObject view = PluginsManagement.Instance.GetView(np.ID);
                    IRegion region = regionManager.Regions["ContentRegion"];
                    RemoveViewsInContentRegion(region);
                    region.Add(view);
                    region.Activate(view);
                    FrameworkElement fe = view as FrameworkElement;
                    if (fe != null)
                    {
                        ViewModelBase vmBase = fe.DataContext as ViewModelBase;
                        if (vmBase != null) vmBase.OnAdded();
                    }
                }
            }
        }

        private void RemoveViewsInContentRegion(IRegion region)
        {

            if (region == null) return;
            if (region.Views.Count() == 1)
            {
                object obj = region.Views.First();
                region.Remove(obj);
                FrameworkElement fe = obj as FrameworkElement;
                if (fe != null)
                {
                    ViewModelBase vmBase = fe.DataContext as ViewModelBase;
                    if (vmBase != null) vmBase.OnRemoved();
                }
            }
        }
    }
}
